/**
 * 
 */
package com.farmerec.utl;

/**
 * @author Administrator 自定义的一些生成随时数的方法
 */
public class RandomCus {
	private static RandomCus ins;

	/**
	 * 私有化其构造函数
	 */
	private RandomCus() {
	}

	/*
	 * 获取单例
	 */
	public static RandomCus getIns() {
		if (ins == null) {
			ins = new RandomCus();
		}
		return ins;
	}

	/**
	 * 生成随机整型数值
	 *
	 * @param 给定区间
	 *            ，在区间内取随机值；
	 * @return int类型，为方便日常使用，设计算法使返回可能的结果中包括最值;
	 */
	public int randomNumberBetween(int min, int max) {
		int re = min;
		if (min < max) {
			re += Math.floor(Math.random() * (max + 1 - min));
		} else {
			re -= Math.floor(Math.random() * (min + 1 - max));
		}
		return re;
	}

	/**
	 * 生成随机单精度浮点型数值
	 *
	 * @param 给定区间
	 *            ，在区间内取随机值；
	 * @return float类型，返回可能的结果中不包括最大值;
	 */
	public float randomNumberBetween(float min, float max) {
		float re = min;
		if (min < max) {
			re += Math.random() * (max - min);
		} else {
			re -= Math.random() * (max - min);
		}
		return re;
	}

	/**
	 * 生成随机双精度浮点型数值
	 *
	 * @param 给定区间
	 *            ，在区间内取随机值；
	 * @return double类型，返回可能的结果中不包括最大值;
	 */
	public double randomNumberBetween(double min, double max) {
		double re = min;
		if (min < max) {
			re += Math.random() * (max - min);
		} else {
			re = Math.random() * (max - min);
		}
		return re;
	}

	/**
	 * 生成随机整型数值
	 *
	 * @param 给定中间数与浮动范围
	 *            ，以中间数为起点，在范围内取随机值；
	 * @return int类型，因为结果是取下整以保证各个数被取得概率一致，返回可能的结果中不包括最值 若要取得最值，将range增加1作为参数传入
	 */
	public int randomNumberSFMediant(int mediant, int range) {
		int re = mediant;
		if (Math.random() < 0.5) {
			re += Math.floor(Math.random() * range);
		} else {
			re -= Math.floor(Math.random() * range);
		}
		return re;
	}

	/**
	 * 生成随机单精度浮点型数值
	 *
	 * @param 给定中间数与浮动范围
	 *            ，以中间数为起点，在范围内取随机值；
	 * @return float类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最值
	 */
	public float randomNumberSFMediant(float mediant, float range) {
		float re = mediant;
		if (Math.random() < 0.5) {
			re += Math.random() * range;
		} else {
			re -= Math.random() * range;
		}
		return re;
	}

	/**
	 * 生成随机双精度浮点型数值
	 * @param 给定中间数与浮动范围
	 *            ，以中间数为起点，在范围内取随机值；
	 * @return 类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最值
	 */
	public double randomNumberSFMediant(double mediant, double range) {
		double re = mediant;
		if (Math.random() < 0.5) {
			re += Math.random() * range;
		} else {
			re -= Math.random() * range;
		}
		return re;
	}

	/**
	 * 生成随机整型数值
	 * @param 给定最小数与浮动范围
	 *            ，以最小数为起点，在范围内取随机值；
	 * @return int类型，同时为保证取范围内各数概率一致，只能对下整，所以返回可能的结果中不包括最大值
	 *         若要取得最值，将range增加1作为参数传入
	 */
	public int randomNumberSFMin(int min, int range) {
		int re = min;
		re += Math.floor(Math.random() * range);
		return re;
	}

	/**
	 * 生成随机单精度浮点型数值
	 * @param 给定最小数与浮动范围
	 *            ，以最小数为起点，在范围内取随机值；
	 * @return float类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最大值
	 */
	public float randomNumberSFMin(float mediant, float range) {
		float re = mediant;
		re += Math.random() * range;
		return re;
	}

	/**
	 * 生成随机双精度浮点型数值
	 * @param 给定最小数与浮动范围
	 *            ，以最小数为起点，在范围内取随机值；
	 * @return double类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最大值
	 */
	public double randomNumberSFMin(double mediant, double range) {
		double re = mediant;
		re += Math.random() * range;
		return re;
	}

	/**
	 * 生成随机整型数值;
	 * @param 给定最大数与浮动范围，以最大数为起点，在范围内取随机值；
	 * @return int类型，同时因为结果是四舍五入取整，返回可能的结果中不包括最小值 若要取得最值，将range增加1作为参数传入
	 */
	public int randomNumberSFMax(int max, int range) {
		int re = max;
		re -= Math.floor(Math.random() * range);
		return re;
	}

	/**
	 * 生成随机单精度浮点型数值; SF:start from;
	 * @param 给定最大数与浮动范围，以最大数为起点，减去范围内随机一个数；
	 * @return float类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最小值;
	 */
	public float randomNumberSFMax(float max, float range) {
		float re = max;
		re -= Math.random() * range;
		return re;
	}

	/**
	 * 生成随机双精度浮点型数值; SF:start from;
	 * @param 给定最大数与浮动范围，以最大数为起点，减去范围内随机一个数；
	 * @return double类型，因为Math.random()返回结果不包括1.0,返回可能的结果中不包括最小值;
	 */
	public double randomNumberSFMax(double max, double range) {
		double re = max;
		re -= Math.random() * range;
		return re;
	}

	/**
	 * 生成指定某一种类型随机字符的方法
	 */
	public char randomChar(CharType type) {
		char re = ' ';
		switch (type) {
		case LOWERCASE:
			re = randomLowercase();
			break;
		case UPPERCASE:
			re = randomUppercase();
			break;
		case NUMBER:
			re = randomNumberChar();
			break;
		case SYMBOL:
			re = randomSymbol();
			break;
		}
		return re;
	}

	/**
	 * 随机生成指定字符类型与长度的字符串
	 * @param type:字符类型
	 * @param length:字符串长度
	 * @return
	 */
	public String randomString(CharType type, int length) {
		String str = "";
		for (int i = 0; i < length; i++) {
			str += this.randomChar(type);
		}
		return str;
	}

	/**
	 * 生成指定某两种类型随机字符的方法
	 */
	public char randomChar(CharType type1, CharType type2) {
		char re = ' ';
		if (Math.random() < 0.5) {
			re = this.randomChar(type1);
		} else {
			re = this.randomChar(type2);
		}
		return re;
	}

	/**
	 * 随机生成指定字符类型（两种）与长度的字符串
	 * @param type1:字符类型1
	 * @param type2：字符类型2
	 * @param length:字符串长度
	 * @return String
	 */
	public String randomString(CharType type1, CharType type2, int length) {
		String str = "";
		for (int i = 0; i < length; i++) {
			str += this.randomChar(type1, type2);
		}
		return str;
	}

	/**
	 * 生成指定某三种类型随机字符的方法
	 */
	public char randomChar(CharType type1, CharType type2, CharType type3) {
		char re = ' ';
		int typeNumber = this.randomNumberBetween(1, 3);
		if (typeNumber == 1) {
			re = this.randomChar(type1);
		} else if (typeNumber == 2) {
			re = this.randomChar(type2);
		} else {
			re = this.randomChar(type3);
		}
		return re;
	}

	/**
	 * 随机生成指定字符类型（三种）与长度的字符串
	 * @param type1：字符类型1
	 * @param type2：字符类型2
	 * @param type3：字符类型3
	 * @param length：字符串长度
	 * @return String
	 */
	public String randomString(CharType type1, CharType type2, CharType type3,
			int length) {
		String str = "";
		for (int i = 0; i < length; i++) {
			str += randomChar(type1, type2, type3);
		}
		return str;
	}

	/**
	 * 生成指定不定类型随机字符的方法 生成的字符类型包括大写字母、小写字母、数字、特殊字符
	 */
	public char randomChar() {
		int typeNumber = this.randomNumberBetween(0, 127);
		char re = (char) typeNumber;
		return re;
	}
	
	/**
	 * 随机生成指定长度的字符串
	 * @param length
	 * @return String
	 */
	public String randomString(int length){
		String str = "";
		for(int i = 0; i < length; i ++){
			str += this.randomChar();
		}
		return str;
	}

	/**
	 * 生成随机数字字符的方法
	 */
	public char randomNumberChar() {
		int tempNumber = randomNumberBetween(48, 57);
		return (char) tempNumber;
	}

	/**
	 * 生成随机大写字母的方法
	 */
	public char randomUppercase() {
		int tempNumber = randomNumberBetween(65, 90);
		return (char) tempNumber;
	}

	/**
	 * 生成随机小写字母的方法
	 */
	public char randomLowercase() {
		int tempNumber = randomNumberBetween(97, 122);
		return (char) tempNumber;
	}

	
	/**
	 * 生成随机特殊符号的方法
	 */
	public char randomSymbol() {
		int partNumber = randomNumberBetween(1, 4);
		int tempNumber = -1;
		switch (partNumber) {
		case 1:
			tempNumber = randomNumberBetween(0, 47);
			break;
		case 2:
			tempNumber = randomNumberBetween(58, 64);
			break;
		case 3:
			tempNumber = randomNumberBetween(91, 96);
			break;
		case 4:
			tempNumber = randomNumberBetween(123, 127);
			break;
		}
		return (char) tempNumber;
	}
}
